/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.hsrm;

/**
 *
 * @author acme
 */
public final class AddressTable {
    
    private static final AddressTable INSTANCE = new AddressTable();
    
    private Car[][][] addressTable = new Car[4][3][Util.MAX_ADRESSES];
    
    private AddressTable()
    {
        resetTable();
    }
    
    public static AddressTable getInstance()
    {
        return INSTANCE;
    }
    
    public synchronized int generateAddress(int addressRequest)
    {
        int location = addressRequest/10;
        int lane = addressRequest%10;
        int car = 0;
        
        for (int k = 1; k < addressTable[location][lane].length; k++)
        {
           if(addressTable[location][lane][k] == null)
           {
                    car = k;
                    break;
           }
        }
                    
        return  10000
                + (location * 1000)
                + (lane * 100)
                + car;
    }
    
//    public synchronized void setAddressTableEntry(int assignedAddr, long sourceMacAddress)
//    {
//        assignedAddr = assignedAddr - 10000;
//        int lane = assignedAddr/1000;
//        int location = (assignedAddr/100)%10;
//        int car = assignedAddr%100;
//        if(addressTable[lane][location][car] == null)
//            addressTable[lane][location][car] = new Car(sourceMacAddress, assignedAddr);
//    }
    
    public synchronized void deleteAddressTableEntry(int assignedAddr)
    {
        assignedAddr = assignedAddr%10000;
        int location = assignedAddr/1000;
        int lane = (assignedAddr/100)%10;
        int car = assignedAddr%100;
        addressTable[location][lane][car] = null;
    }
    
    public synchronized void addAddressTableEntry(int assignedAddr, long macAddress)
    {
        int tmp = assignedAddr%10000;
        int location = tmp/1000;
        int lane = (tmp/100)%10;
        int car = tmp%100;
        System.out.println("\nAddress Table updated?:\n"
                                + "address: " + String.valueOf(assignedAddr));
        //if(addressTable[location][lane][car] != null && addressTable[location][lane][car].getMacAddress() == macAddress)
        //    addressTable[location][lane][car].setWaitTime(addressTable[location][lane][car].getWaitTime()+1);
        if(addressTable[location][lane][car] == null)
        {
            addressTable[location][lane][car] = new Car(macAddress, assignedAddr);
            System.out.println("ok");
        }
        else
            System.out.println("not ok");
            
    }
    
    public synchronized void updateAddressTableEntry(int assignedAddr, long macAddress, boolean ckecked)
    {
        int tmp = assignedAddr%10000;
        int location = tmp/1000;
        int lane = (tmp/100)%10;
        int car = tmp%100;
        System.out.println("\nAddress Table updated?:\n"
                                + "address: " + String.valueOf(assignedAddr));
        if(addressTable[location][lane][car] != null && addressTable[location][lane][car].getMacAddress() == macAddress)
        {
            addressTable[location][lane][car].setWaitTime(addressTable[location][lane][car].getWaitTime()+1);
            addressTable[location][lane][car].setChecked(true);
        }
        else if(addressTable[location][lane][car] == null)
        {
            addressTable[location][lane][car] = new Car(macAddress, assignedAddr);
            System.out.println("ok");
        }
        else
            System.out.println("not ok");
            
    }
    
    public Car getCar(int assignedAddr)
    {
        assignedAddr = assignedAddr%10000;
        int location = assignedAddr/1000;
        int lane = (assignedAddr/100)%10;
        int car = assignedAddr%100;
        return addressTable[location][lane][car];
    }
    
    public int getLaneWaitTime(int location, int lane)
    {
        int result = 0;
        for(int i = 0; i < addressTable[location][lane].length; i++)
        {
            if(addressTable[location][lane][i] != null)
                result = result + addressTable[location][lane][i].getWaitTime();
        }
        return result;
    }
    
    public void updateLaneWaitTime(int location, int lane)
    {
        int result = 0;
        for(int i = 0; i < addressTable[location][lane].length; i++)
        {
            if(addressTable[location][lane][i] != null)
                addressTable[location][lane][i].incrementWaitTime();
        }
    }
    public void resetTable()
    {
       for (int i = 0; i < addressTable.length; i++)
        {
            for (int j = 0; j < addressTable[i].length; j++)
            {
                for (int k = 0; k < addressTable[i][j].length; k++)
                {
                    addressTable[i][j][k] = null;
                }   
            }
        } 
    }
}
